package com.example.websocket.component;


import com.example.websocket.Service.MessageService;
import com.example.websocket.Service.UserService;
import com.example.websocket.Utils.MessageUtils;
import com.example.websocket.config.GetHttpSessionConfigurator;
import com.example.websocket.pojo.Message;
import com.example.websocket.pojo.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/chat",configurator = GetHttpSessionConfigurator.class)
@Component
public class ChatEndpoint {

    private static UserService userService;
    private static MessageService messageService;
    //由于ChatEndpoint和spring的单例模式冲突，需要添加一个set方法来使用UserService
    @Autowired
    private void setUserService(UserService userService){
        ChatEndpoint.userService = userService;
    }
    @Autowired
    private void setMessageService(MessageService messageService) {
        ChatEndpoint.messageService = messageService;
    }

    //用来存储每个用户客户端对象的ChatEndpoint对象
    private static Map<String,ChatEndpoint> onlineUsers = new ConcurrentHashMap<>();

    //声明session对象，通过对象可以发送消息给指定的用户
    private Session session;

    //声明HttpSession对象，我们之前在HttpSession对象中存储了用户名
    private HttpSession httpSession;

    //连接建立
    @OnOpen
    public void onOpen(Session session, EndpointConfig config){
        this.session = session;
        HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        this.httpSession = httpSession;
        //存储登陆的对象
        String username = (String)httpSession.getAttribute("username");
        onlineUsers.put(username,this);
        //将当前在线用户的用户名推送给所有的客户端
        //1 获取消息
        String message = MessageUtils.getMessage(true, null, getNames());
        //2 调用方法进行系统消息的推送
        broadcastAllUsers(message);
    }

    private void broadcastAllUsers(String message){
        try {
            //将消息推送给所有的客户端
            Set<String> names = onlineUsers.keySet();
            //存储登陆的对象
            String username = (String)httpSession.getAttribute("username");
            //将在线用户和好友列表进行比对，只展示好友的信息
            for (String name : names) {
                //查询新登录的用户是否为他人的好友
                List<User> Friends = userService.GetFriend(name);
                for(User friend : Friends){
                    if(username.equals(friend.getName())){
                        ChatEndpoint chatEndpoint = onlineUsers.get(name);
                        //比对在线用户和好友
                        String friends = MessageUtils.getMessage(true, null, getFriends(name));
                        chatEndpoint.session.getBasicRemote().sendText(friends);
                    }
                }
                //显示新登录的用户的好友列表
                ChatEndpoint chatEndpoint = onlineUsers.get(username);
                //比对在线用户和好友
                String friends = MessageUtils.getMessage(true, null, getFriends(username));
                chatEndpoint.session.getBasicRemote().sendText(friends);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //返回在线用户名
    private Set<String> getNames(){
        return onlineUsers.keySet();
    }

    //返回好友
    private Set<String> getFriends(String name){
        //根据登录的用户去查询用户的好友
        List<User> Friends = userService.GetFriend(name);
        //将在线用户和好友列表进行比对，只展示好友的信息
        Set<String> FriendsSet = new HashSet<String>();
        for(User friend : Friends){
            Set<String> AllLiner = getNames();
            for(String Liner : AllLiner){
                if(friend.getName().equals(Liner)){
                    FriendsSet.add(friend.getName());
                }
            }
        }
        return FriendsSet;
    }

    //收到消息
    @OnMessage
    public void onMessage(String message,Session session){
        //将数据转换成对象
        try {
            ObjectMapper mapper =new ObjectMapper();
            Message mess = mapper.readValue(message, Message.class);
            //toName:要发送的对象 data:对话内容 username:发送者
            String toName = mess.getToName();
            String data = mess.getMessage();
            String username = (String) httpSession.getAttribute("username");
            //聊天消息存入数据库
            mess.setUsername(username);
            messageService.save(mess);
            String resultMessage = MessageUtils.getMessage(false, username, data);
            //发送数据
            onlineUsers.get(toName).session.getBasicRemote().sendText(resultMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    //关闭
    @OnClose
    public void onClose(Session session) {
        String username = (String) httpSession.getAttribute("username");
        //从容器中删除指定的用户
        onlineUsers.remove(username);
        MessageUtils.getMessage(true,null,getNames());
    }}

